/*============================================================================
 PROJECT: DealHits
 FILE:    PhotoGalleryViewController.m
 AUTHOR:  Khoai Nguyen Minh
 DATE:    9/19/13
 =============================================================================*/

/*============================================================================
 IMPORT
 =============================================================================*/
#import "PhotoGalleryViewController.h"
#import "PhotoGalleryView.h"
#import "SVPullToRefresh.h"
#import "UIView+ShowAnimations.h"
#import "GMGridView.h"
#import "PhotoGalleryCell.h"
#import "PickPhotoView.h"
#import "FileRequestQueueManager.h"

/*============================================================================
 PRIVATE MACRO
 =============================================================================*/
#define kTagNumber  99

typedef enum {
    kEditNavigationBarButtonTypeDone,
    kEditNavigationBarButtonTypeUpload
} EditNavigationBarButtonType;

#define kUploadNavigationBarButtonTitle     NSLocalizedString(@"Upload", @"NavigationBar Right Button")
#define kDoneNavigationBarButtonTitle     NSLocalizedString(@"Done", @"NavigationBar Right Button")

/*============================================================================
 PRIVATE INTERFACE
 =============================================================================*/


@interface PhotoGalleryViewController ()<UITableViewDataSource, UITableViewDelegate, GMGridViewDataSource, GMGridViewActionDelegate> {
    NSInteger currentPage;
    NSInteger canLoadMore;
    __gm_weak GMGridView *_gmGridView;
    EditNavigationBarButtonType editButtonType;
}

@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) IBOutlet UILabel *captionLabel;
@property (strong, nonatomic) IBOutlet UIView *topBarView;
@property (strong, nonatomic) FileRequestBlock requestBlock;

@end

@implementation PhotoGalleryViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)awakeFromNib {
    
}

- (void)viewDidLoad {
    
    self.rightButtonTitle = (self.editing ? kUploadNavigationBarButtonTitle : kDoneNavigationBarButtonTitle);
    self.hiddenRightButton = NO;
    
    [super viewDidLoad];
    self.selectedIndexes = [NSMutableIndexSet indexSet];
    
    // Do any additional setup after loading the view from its nib.
    self.titleLabel.text = NSLocalizedString(@"Photos", @"Navigation Bar Title");
    CallTargetWith2Obj(self.delegate, @selector(gallery:textForTitleLabel:), self, self.captionLabel);
    
    /* settings for top bar view */
    LayerShadow(self.topBarView.layer, UIColorFromRGB(0x5a5a5a), 1);
    
    /* settings for grid view */
    CGFloat captionLabelHeight = _topBarView.frame.size.height;
    CGSize size = kScreenFrame.size;
    CGRect rect = CGRectMake(0, captionLabelHeight, size.width, size.height - captionLabelHeight - 20);
    
    if(IS_IPAD) {
        rect.origin.y += self.customNavigationBar.frame.size.height;
        rect.size.height -= self.customNavigationBar.frame.size.height;
    }
    
    /* create grid view */
    GMGridView *gmGridView = [[GMGridView alloc] initWithFrame:rect];
    gmGridView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    gmGridView.backgroundColor = [UIColor clearColor];
    [self.view insertSubview:gmGridView belowSubview:self.topBarView];
    _gmGridView = gmGridView;
    
    NSInteger spacing = (IS_IPAD ? 20 : 10);
    _gmGridView.style = GMGridViewStylePush;
    _gmGridView.itemSpacing = spacing;
    _gmGridView.disableEditOnEmptySpaceTap = YES;
    
    _gmGridView.minEdgeInsets = UIEdgeInsetsMake(spacing, spacing, spacing, spacing);
    _gmGridView.centerGrid = NO;
    _gmGridView.dataSource = self;
    
    /* setting table view to show photo detail */
    self.tableView = [[UITableView alloc] initWithFrame:rect style:UITableViewStylePlain];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    self.tableView.pagingEnabled = YES;
    self.tableView.showsVerticalScrollIndicator = NO;
    self.tableView.showsHorizontalScrollIndicator = NO;
    self.tableView.backgroundColor = [UIColor blackColor];
    self.tableView.transform = CGAffineTransformMakeRotation(-M_PI_2);
    
    [self.view addSubview:self.tableView];
    self.tableView.frame = rect;
    self.tableView.alpha = 0;
    
    /* update right button on navigation bar */
    if(self.editing) {
        editButtonType = kEditNavigationBarButtonTypeUpload;
    } else {
        editButtonType = kEditNavigationBarButtonTypeDone;
    }
    
    if(IS_IPAD) {
        self.customNavigationBar.rightBarButton.hidden = !self.editing;
    } else {
        self.navigationItem.rightBarButtonItem.customView.hidden = !self.editing;
    }
}

- (void)viewDidUnload {
    [self setCaptionLabel:nil];
    [self setTopBarView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Event Button

- (void)changeRightButtonBarName:(NSString *)name visible:(BOOL)visible {
    self.rightButtonImageName = name;
    if(IS_IPAD) {
        [self.customNavigationBar.rightBarButton setTitle:self.rightButtonImageName forState:UIControlStateNormal];
        
        CGSize size = [Utils constrainSizeForLabel:self.customNavigationBar.rightBarButton.titleLabel autoFitSize:AutoFitSizeHeight];
        
        CGRect rect = self.customNavigationBar.rightBarButton.frame;
        rect.size.width = size.width + (IS_IPAD ? 20 : 10);
        rect.origin.x = CGRectGetMaxX(rect) - rect.size.width;
        self.customNavigationBar.rightBarButton.frame = rect;
        
        [self.customNavigationBar.rightBarButton addTarget:self action:@selector(didTouchedOnRightButton:) forControlEvents:UIControlEventTouchUpInside];
        if(self.editing) {
            self.customNavigationBar.leftBarButton.hidden = (editButtonType == kEditNavigationBarButtonTypeDone && visible ? !visible : visible);
        } else {
            self.customNavigationBar.leftBarButton.hidden = visible;
        }
    } else {
        for (UIView *view in self.navigationItem.rightBarButtonItem.customView.subviews) {
            if([view isKindOfClass:[UIButton class]]) {
                [(UIButton *)view setTitle:self.rightButtonImageName forState:UIControlStateNormal];
                CGSize size = [Utils constrainSizeForLabel:((UIButton *)view).titleLabel autoFitSize:AutoFitSizeHeight];
                view.frame = CGRectMake(0, 0, size.width + (IS_IPAD ? 20 : 10), 30);
                
                CGRect rect = self.navigationItem.rightBarButtonItem.customView.frame;
                rect.size.width = view.frame.size.width + self.navigationBarButtonPadding;
                rect.origin.x = CGRectGetMaxX(rect) - rect.size.width;
                self.navigationItem.rightBarButtonItem.customView.frame = rect;
            }
        }
        self.navigationItem.rightBarButtonItem.customView.hidden = !visible;
        if(self.editing) {
            self.navigationItem.leftBarButtonItem.customView.hidden = (editButtonType == kEditNavigationBarButtonTypeDone && visible ? !visible : visible);
        } else {
            self.navigationItem.leftBarButtonItem.customView.hidden = visible;
        }
    }
}

- (void)didTouchedOnRightButton:(id)sender {
    
    if(editButtonType == kEditNavigationBarButtonTypeDone) {
        if(self.editing) {
            [self changeRightButtonBarName:kUploadNavigationBarButtonTitle visible:YES];
        } else {
            [self changeRightButtonBarName:kDoneNavigationBarButtonTitle visible:NO];
        }
        
        if(editButtonType == kEditNavigationBarButtonTypeDone) {
            editButtonType = kEditNavigationBarButtonTypeUpload;
        } else {
            editButtonType = kEditNavigationBarButtonTypeDone;
        }
        
        /* hide photo detail */
        [UIView animateWithDuration:0.15f
                              delay:0
                            options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve)
                         animations:^{
                             self.tableView.alpha = 0.0;
                         }
                         completion:^(BOOL finished) {
                             
                         }];
    } else {
        /* upload photo */
        PickPhotoView *pickView = [PickPhotoView sharedPickPhotoView];
        [[PickPhotoView sharedPickPhotoView] showOnViewController:self
                                                          forType:kPhotoPickerTypeOthers
                                                      resultBlock:^(UIImage *pickedImage, BOOL cancel) {}];
        
        pickView.getPhotoAssetURLCallback = ^(NSURL *assetURL) {
            
            /* create file request for upload queue */
            FileRequest *fileRequest = [FileRequest fileWithURL:assetURL.absoluteString
                                                           name:[assetURL.absoluteString lastPathComponent]
                                                     identifier:assetURL.absoluteString];
            fileRequest.parentId = self.parentId;
            
            /* create request file block */
            if(!self.requestBlock) {
                __weak PhotoGalleryViewController *weakSelf = self;
                self.requestBlock = ^(FileRequest *fileRequest, CGFloat percentage, NSError *error) {
                    if(percentage == kFileRequestProgressTypeFinished && !error) {
                        /* reload photo gallery */
                        if(weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(didUploadedPhotoInGallery:)]) {
                            [weakSelf.delegate didUploadedPhotoInGallery:weakSelf];
                        }
                    }
                };
            }
            
            /* add photo into upload queue */
            FileRequestQueueManager *manager = [FileRequestQueueManager sharedManager];
            [manager uploadFile:fileRequest usingBlock:self.requestBlock];
            
            /* update UI */
            if(self.delegate && [self.delegate respondsToSelector:@selector(didAddedPhotoIntoUploadQueue:)]) {
                [self.delegate didAddedPhotoIntoUploadQueue:self];
            }
        };
    }
}

#pragma mark - support methods

- (void)updateSelectedIndexes:(NSIndexSet *)selectedIndexes {
    [self.selectedIndexes removeAllIndexes];
    [self.selectedIndexes addIndexes:selectedIndexes];
    
    double delayInSeconds = 0.01;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self reloadData];
    });
}

/*----------------------------------------------------------------------------
 Method:      loadPlacesForceRefresh
 Description: load places via API with force reload option
 -----------------------------------------------------------------------------*/
- (void)loadPlacesForceRefresh:(BOOL)forceRefresh {
    
    if (forceRefresh) {
        currentPage = 1;
        canLoadMore = YES;
    } else {
        if (canLoadMore) {
            currentPage++;
        }
    }
    
    if (canLoadMore) {
        [_gmGridView.pullToRefreshView stopAnimating];
    } else {
        [_gmGridView.pullToRefreshView stopAnimating];
    }
    
    [self showLoadingView];
    [_gmGridView reloadData];
    [self.tableView reloadData];
    [self hideLoadingView];
}

/*----------------------------------------------------------------------------
 Method:      reloadData
 Description: reload places via API at page 0
 -----------------------------------------------------------------------------*/
- (void)reloadData {
    if(!self.processing) {
        [self loadPlacesForceRefresh:YES];
    }
}

/*----------------------------------------------------------------------------
 Method:      loadMoreData
 Description: load more places with the old condition
 -----------------------------------------------------------------------------*/
- (void)loadMoreData {
    [self loadPlacesForceRefresh:NO];
}

- (void)scrollToCell:(PhotoGalleryView *)cell {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:cell.tag inSection:0];
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
}

//////////////////////////////////////////////////////////////
#pragma mark GMGridViewDataSource
//////////////////////////////////////////////////////////////

- (NSInteger)numberOfItemsInGMGridView:(GMGridView *)gridView {
    if(self.delegate && [self.delegate respondsToSelector:@selector(numberOfPhotosInGallery:)]) {
        return [self.delegate numberOfPhotosInGallery:self];
    }
    return 0;
}

- (CGSize)GMGridView:(GMGridView *)gridView sizeForItemsInInterfaceOrientation:(UIInterfaceOrientation)orientation {
    return CGSizeMake(kPhotoGalleryViewHeight, kPhotoGalleryViewHeight);
}

- (void)updateStatus:(BOOL)status ofCellsAtIndexSet:(NSIndexSet *)set {
    /* unselect other cells */
    NSUInteger index = [set firstIndex];
    for (int i = 0; i < set.count; i++) {
        GMGridViewCell *oldCell = [_gmGridView cellForItemAtIndex:index];
        PhotoGalleryView *view = (PhotoGalleryView *)oldCell.contentView;
        view.selectButton.selected = status;
        index = [set indexGreaterThanIndex:index];
    }
}

- (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index {
    
    CGSize size = [self GMGridView:gridView sizeForItemsInInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
    GMGridViewCell *cell = [gridView dequeueReusableCell];
    
    if (!cell) {
        cell = [[GMGridViewCell alloc] init];
        cell.deleteButtonIcon = [UIImage imageNamed:@"close_x.png"];
        cell.deleteButtonOffset = CGPointMake(-15, -15);
        
        /* create customize view */
        PhotoGalleryView *view = [[IBHelper sharedUIHelper] loadViewNib:@"PhotoGalleryView"];
        view.frame = CGRectMake(0, 0, size.width, size.height);
        view.viewPhotoBlock = ^(PhotoGalleryView *photoGalleryView) {
            
            /* add right button */
            [self changeRightButtonBarName:kDoneNavigationBarButtonTitle visible:YES];
            editButtonType = kEditNavigationBarButtonTypeDone;
            
            NSInteger idx = (photoGalleryView.tag - kTagNumber);
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:0]
                                  atScrollPosition:UITableViewScrollPositionTop animated:NO];
            
            /* show photo detail */
            [UIView animateWithDuration:0.15f
                                  delay:0
                                options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve)
                             animations:^{
                                 self.tableView.alpha = 1.0;
                             }
                             completion:^(BOOL finished) {
                                 
                             }];
        };
        
        view.selectPhotoBlock = ^(PhotoGalleryView *photoGalleryView) {
            if (photoGalleryView.selectButton.selected) {
                
                /* update status */
                [self updateStatus:NO ofCellsAtIndexSet:self.selectedIndexes];
                
                /* show popup to confirm it */
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
                                                                    message:NSLocalizedString(@"Set Placeholder Photo", @"PlaceHolder")
                                                                   delegate:nil
                                                          cancelButtonTitle:NSLocalizedString(@"Cancel", @"UIButton")
                                                          otherButtonTitles:NSLocalizedString(@"OK", @"UIButton"), nil];
                
                [alertView showWithCompleteHandler:^(UIAlertView *alertView, NSInteger buttonIndex) {
                    if (buttonIndex == 1) { // OK
                        NSInteger idx = (photoGalleryView.tag - kTagNumber);
                        [self.selectedIndexes removeAllIndexes];
                        [self.selectedIndexes addIndex:idx];
                        
                        if(self.delegate && [self.delegate respondsToSelector:@selector(gallery:selectedPhotoAtIndex:)]) {
                            [self.delegate gallery:self selectedPhotoAtIndex:idx];
                        }
                        [self.navigationController popViewControllerAnimated:YES];
                    } else {
                        photoGalleryView.selectButton.selected = NO;
                        [self updateStatus:YES ofCellsAtIndexSet:self.selectedIndexes];
                    }
                    
                }];
            } else {
                [self.selectedIndexes removeIndex:photoGalleryView.tag];
            }
        };
        
        cell.contentView = view;
        view.selectButton.hidden = !self.editing;
    }
    
    /* update data */
    cell.contentView.tag = (index + kTagNumber);
    
    /* update photo here */
    if(self.delegate && [self.delegate respondsToSelector:@selector(gallery:photoAtIndex:)]) {
        [(PhotoGalleryView *)cell.contentView setRequest:[self.delegate gallery:self photoAtIndex:index]];
    }
    
    /* update seleted status */
    [(PhotoGalleryView *)cell.contentView selectButton].selected = NO;
    if([self.selectedIndexes containsIndex:index]) {
        [(PhotoGalleryView *)cell.contentView selectButton].selected = YES;
    }
    return cell;
}


- (BOOL)GMGridView:(GMGridView *)gridView canDeleteItemAtIndex:(NSInteger)index {
    return YES;
}

//////////////////////////////////////////////////////////////
#pragma mark GMGridViewActionDelegate
//////////////////////////////////////////////////////////////

- (void)GMGridView:(GMGridView *)gridView didTapOnItemAtIndex:(NSInteger)position {
    
}

- (void)GMGridViewDidTapOnEmptySpace:(GMGridView *)gridView {
    
}

- (void)GMGridView:(GMGridView *)gridView processDeleteActionForItemAtIndex:(NSInteger)index {
    
}

#pragma mark - UITableViewDataSource & UITableViewDelegate

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if(self.delegate && [self.delegate respondsToSelector:@selector(numberOfPhotosInGallery:)]) {
        return [self.delegate numberOfPhotosInGallery:self];
    }
    return 0;
    
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return self.tableView.frame.size.width;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellId = @"PhotoGalleryCell";
    PhotoGalleryCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if(!cell) {
        cell = [[PhotoGalleryCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.backgroundColor = [UIColor clearColor];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        
        cell.callback = ^(PhotoGalleryCell *aCell) {
            NSInteger index = [tableView indexPathForCell:aCell].row;
            
            /* delete photo by calling API first */
            if(self.delegate && [self.delegate respondsToSelector:@selector(gallery:removePhotoAtIndex:)]) {
                [self.delegate gallery:self removePhotoAtIndex:index];
            }
        };
    }
    
    /* update photo here */
    if(self.delegate && [self.delegate respondsToSelector:@selector(gallery:photoAtIndex:)]) {
        [cell setRequest:[self.delegate gallery:self photoAtIndex:indexPath.row]];
    }
    
    /* don't show delete button if it's cover photo */
    cell.deleteButton.hidden = NO;
    NSUInteger idx = [self.selectedIndexes firstIndex];
    for (int i = 0; i < self.selectedIndexes.count; i++) {
        if(idx == indexPath.row) {
            cell.deleteButton.hidden = YES;
            break;
        }
        idx = [self.selectedIndexes indexGreaterThanIndex:idx];
    }
    return cell;
}

@end
